﻿using System;
using System.Collections.Concurrent;
using System.Text;
using Newtonsoft.Json;

namespace SocketServer
{
    public class ReceiveDataUnpack
    {
        private const int HEAD_SIZE = 4;
        private const int BUFFER_SIZE = 7;
        private byte[] dataBuffer = new byte[BUFFER_SIZE];
        
        private byte[] SecondtempBuffer= new byte[0];
        private byte[] tempBuffer;
        int tempBufferIndex = 0;
        

        private String receiveString;
        private int receiveBufferNum = 0;
        private int ContentNum = 0;
        private int remaindContent = 0;
        
        private bool isFirstCopy = true;
        private bool isReadHead = true;
        private bool isReceiveAll = true;
        private bool isread = false;
        private bool isDone = false;
        private bool isHeadBufferHaveNum = false;
        public byte[] DataBuffer
        {
            get { return dataBuffer; }
        }

        public String ReceiveStr
        {
            get { return receiveString; }
        }

        public bool isRead
        {
            get { return isread; }
        }
        
        public void SetDefault()
        {  
            isReadHead = true;
            isFirstCopy = true;
            isReceiveAll = true;
            isread = false;
            isDone = false;
        }


        public void ReadMessage(int count)
        {
             receiveBufferNum += count;
             if (isReadHead)
             {
                 if (SecondtempBuffer.Length<4)
                 {
                     byte[] handBuffer = new byte[HEAD_SIZE]; 
                     Array.Copy(SecondtempBuffer, 0, handBuffer, 0, SecondtempBuffer.Length);
                     Array.Copy(dataBuffer, 0, handBuffer, SecondtempBuffer.Length,HEAD_SIZE- SecondtempBuffer.Length);
                     ContentNum = BitConverter.ToInt32(handBuffer, 0);
                     isFirstCopy = true;
                 }
                 else if(SecondtempBuffer.Length==4)
                 {
                     ContentNum = BitConverter.ToInt32(SecondtempBuffer, 0);
                     isFirstCopy = true;
                 }
                 else if (SecondtempBuffer.Length>4)
                 {
                     ContentNum = BitConverter.ToInt32(SecondtempBuffer, 0);
                     Array.Copy(SecondtempBuffer, HEAD_SIZE, tempBuffer, 0, SecondtempBuffer.Length-HEAD_SIZE);
                     isFirstCopy = false;
                     isHeadBufferHaveNum = true;
                 }
                 tempBuffer = new byte[ContentNum];
                 remaindContent = ContentNum;
                 
                 if (receiveBufferNum>ContentNum)
                 {
                     isReceiveAll = true;
                 }
                 else
                 {
                     isReceiveAll = false;
                 }
                 
                 isReadHead = false;
                 isread = false;
             }
             
             if (remaindContent > 0 &&!isReceiveAll)
             {
                 if (isFirstCopy)
                 {
                     
                     Array.Copy(dataBuffer, HEAD_SIZE- SecondtempBuffer.Length, tempBuffer, 0, receiveBufferNum - HEAD_SIZE + SecondtempBuffer.Length);
                     remaindContent -= receiveBufferNum - HEAD_SIZE + SecondtempBuffer.Length;
                     tempBufferIndex = receiveBufferNum - HEAD_SIZE + SecondtempBuffer.Length;
                     isFirstCopy = false;
                 }
                 else if (isHeadBufferHaveNum)
                 {
                     Array.Copy(SecondtempBuffer, HEAD_SIZE, tempBuffer, 0, SecondtempBuffer.Length-HEAD_SIZE);
                     Array.Copy(dataBuffer, 0, tempBuffer, SecondtempBuffer.Length-HEAD_SIZE,count);
                     remaindContent -= SecondtempBuffer.Length-HEAD_SIZE + count;
                     tempBufferIndex = SecondtempBuffer.Length-HEAD_SIZE + count;
                     isHeadBufferHaveNum=false;
                 }
                 else 
                 {
                     if (remaindContent<=count)
                     {
                         Array.Copy(dataBuffer, 0, tempBuffer, tempBufferIndex, remaindContent);
                         isDone = true;
                         if (count-remaindContent<=HEAD_SIZE)
                         {
                             SecondtempBuffer = new byte[count-remaindContent];
                             Array.Copy(dataBuffer, remaindContent, SecondtempBuffer, 0, count-remaindContent);
                         }
                         else
                         {
                             SecondtempBuffer = new byte[count-remaindContent];
                             Array.Copy(dataBuffer, remaindContent, SecondtempBuffer, 0, count-remaindContent);
                         }
                     }
                     else
                     {
                         Array.Copy(dataBuffer, 0, tempBuffer, tempBufferIndex, count);
                         remaindContent -= count;
                         if (remaindContent==0)
                         {
                             isDone = true;
                         }
                     }
                     tempBufferIndex += dataBuffer.Length;
                 }
             }
             
             if (isReceiveAll)
             {
                 Array.Copy(dataBuffer,HEAD_SIZE,tempBuffer,0,tempBuffer.Length);
                 isDone = true;
             }

             if(isDone)
             {
                 isread = true;
                 receiveString = Encoding.UTF8.GetString(tempBuffer, 0, tempBuffer.Length);
                 receiveBufferNum = 0;
                 isReadHead = true;
                 isDone = false;
             }
        }
    }
}